// SkinHeaderCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "BBSimple.h"
#include "SkinHeaderCtrl.h"
#include "memdc.h"

#include "../_inc/def_base.h"


// CSkinHeaderCtrl

IMPLEMENT_DYNAMIC(CSkinHeaderCtrl, CHeaderCtrl)

CSkinHeaderCtrl::CSkinHeaderCtrl()
{
	m_nChkState		= 1;
	m_pParentWnd	= NULL;
	m_nCtrlID = 0;
	m_nFontHeight = 16;
}

CSkinHeaderCtrl::~CSkinHeaderCtrl()
{
}


BEGIN_MESSAGE_MAP(CSkinHeaderCtrl, CHeaderCtrl)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()



// CSkinHeaderCtrl message handlers

int CSkinHeaderCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CHeaderCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;

	return 0;
}

void CSkinHeaderCtrl::InitHeader(CWnd* pWnd)
{
	m_cImageList.Create(13, 13, ILC_COLOR24, 3, 1);
	CBitmap bitmap, *pOldBmpTarget;
	CBitmap *pBmp, *pOldBmpSource;
	BITMAP bm;
	CDC dcMemory1, dcMemory2;
	CPaintDC dc(this);
	dcMemory1.CreateCompatibleDC(&dc);
	dcMemory2.CreateCompatibleDC(&dc);

	CString strImage;
	strImage.Format(_T("%s\\list\\bitmap2.bmp"), theApp.m_strImageRoot);

	HBITMAP hbmpImage;
	hbmpImage = (HBITMAP)LoadImage(GetModuleHandle(NULL), strImage, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);
	pBmp = CBitmap::FromHandle(hbmpImage);
	if (pBmp)
	{
		pBmp->GetObject(sizeof(bm), &bm);
		bitmap.CreateBitmapIndirect(&bm);

		pOldBmpTarget = dcMemory1.SelectObject(&bitmap);
		pOldBmpSource = dcMemory2.SelectObject(pBmp);

		dcMemory1.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMemory2, 0, 0, SRCCOPY);
		dcMemory2.SelectObject(pOldBmpSource);
		dcMemory1.SelectObject(pOldBmpTarget);

		m_cImageList.Add(&bitmap, RGB(255, 0, 255));
	}
	dcMemory1.DeleteDC();
	dcMemory2.DeleteDC();

	SetImageList(&m_cImageList);
	DeleteObject(hbmpImage);
	m_pParentWnd = pWnd;
}

void CSkinHeaderCtrl::InitHeader(CWnd* pWnd, BOOL bCheckbox, int nCtrlID, int nFontHeight)
{
	if (nFontHeight<14)
		m_nCheckBoxHeight = 9;
	else
		m_nCheckBoxHeight = 13;
	m_cImageList.Create(m_nCheckBoxHeight, m_nCheckBoxHeight, ILC_COLOR24, 3, 1);
	if (bCheckbox)
	{
		CBitmap bitmap, *pOldBmpTarget;
		CBitmap *pBmp, *pOldBmpSource;
		BITMAP bm;
		CDC dcMemory1, dcMemory2;
		CPaintDC dc(this);
		dcMemory1.CreateCompatibleDC(&dc);
		dcMemory2.CreateCompatibleDC(&dc);

		CString strImage;
		HBITMAP hbmpImage;
		if (nFontHeight<14)
		{
			strImage.Format(_T("%s\\list\\bitmap3.bmp"), theApp.m_strImageRoot);
			hbmpImage = (HBITMAP)LoadImage(GetModuleHandle(NULL), strImage, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);
		}
		else
		{
			strImage.Format(_T("%s\\list\\bitmap2.bmp"), theApp.m_strImageRoot);
			hbmpImage = (HBITMAP)LoadImage(GetModuleHandle(NULL), strImage, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);
		}
		pBmp = CBitmap::FromHandle(hbmpImage);
		if (pBmp)
		{
			pBmp->GetObject(sizeof(bm), &bm);
			bitmap.CreateBitmapIndirect(&bm);

			pOldBmpTarget = dcMemory1.SelectObject(&bitmap);
			pOldBmpSource = dcMemory2.SelectObject(pBmp);

			dcMemory1.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMemory2, 0, 0, SRCCOPY);
			dcMemory2.SelectObject(pOldBmpSource);
			dcMemory1.SelectObject(pOldBmpTarget);

			m_cImageList.Add(&bitmap, RGB(255, 0, 255));
		}
		dcMemory1.DeleteDC();
		dcMemory2.DeleteDC();
		DeleteObject(hbmpImage);
	}
	SetImageList(&m_cImageList);
	
	m_pParentWnd = pWnd;
	m_nCtrlID = nCtrlID;
	m_nFontHeight = nFontHeight;
	m_bCheckbox = bCheckbox;
}

void CSkinHeaderCtrl::OnPaint()
{
	CPaintDC dc(this);

	CRect rect, rectItem, clientRect;
	GetClientRect(&rect);
	GetClientRect(&clientRect);
	CMemoryDC memDC(&dc, rect);
	CDC bitmapDC;
//	int nHeight;
	bitmapDC.CreateCompatibleDC(&dc);

	memDC.FillSolidRect(&rect, RGB(76,85,118));

	CBitmap *pBmp, *pOldBmp;
	HBITMAP hbmpImage_span;
	HBITMAP hbmpImage_start;
	HBITMAP hbmpImage_end;

	CString strImage;
	strImage.Format(_T("%s\\list\\header_span.bmp"), theApp.m_strImageRoot);
	hbmpImage_span = (HBITMAP)LoadImage(GetModuleHandle(NULL), strImage, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);
	pBmp = CBitmap::FromHandle(hbmpImage_span);
	pOldBmp = bitmapDC.SelectObject(pBmp);

// 	if (lpWndPos->nMode == 1)
// 	{
// 		memDC.StretchBlt(rect.left, 0, rect.Width(), rect.Height(), &bitmapDC, 0, 0, 1, rect.Height(), SRCCOPY);
// 		memDC.StretchBlt(rect.left, rect.Height()-2, rect.Width(), 2, &bitmapDC, 0,	lpBmpInfo->rtImageRect.Height()-2, 1, 2, SRCCOPY);
// 	}
// 	else
	{
		memDC.StretchBlt(rect.left, 0, rect.Width(), 24, &bitmapDC, 0, 0, 1, 24, SRCCOPY);
	}

	bitmapDC.SelectObject(pOldBmp);

	int nItems = GetItemCount();

	CBitmap *pBmpStart, *pBmpEnd, *pBmpSpan;

	CWnd *pListCtrl;
	CFont *pFont;
	if (m_nCtrlID != 0)
	{
		pListCtrl = GetDlgItem(m_nCtrlID);
		if (pListCtrl)
			pFont = pListCtrl->GetFont();
	}

	strImage.Format(_T("%s\\list\\header_start.bmp"), theApp.m_strImageRoot);
	hbmpImage_start = (HBITMAP)LoadImage(GetModuleHandle(NULL), strImage, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);

	strImage.Format(_T("%s\\list\\header_span.bmp"), theApp.m_strImageRoot);
	hbmpImage_span = (HBITMAP)LoadImage(GetModuleHandle(NULL), strImage, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);

	strImage.Format(_T("%s\\list\\header_end.bmp"), theApp.m_strImageRoot);
	hbmpImage_end = (HBITMAP)LoadImage(GetModuleHandle(NULL), strImage, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);

	pBmpStart = CBitmap::FromHandle(hbmpImage_start);
	pBmpSpan = CBitmap::FromHandle(hbmpImage_span);
	pBmpEnd = CBitmap::FromHandle(hbmpImage_end);

	for(int i = 0; i <nItems; i++)
	{

		TCHAR buf1[256];
		HD_ITEM hditem1;

		hditem1.mask = HDI_TEXT | HDI_FORMAT | HDI_ORDER | HDI_IMAGE;
		hditem1.pszText = buf1;
		hditem1.cchTextMax = 255;
		GetItem( i, &hditem1 );

		GetItemRect(i, &rect);

		CBitmap* pOldBitmap = NULL;

		//make sure we draw the start piece
		//on the first item so it has a left border

		//span the bitmap for the width of the column header item
		int nWidth = rect.Width() - 1;

		/*
		CBitmap* pOldBitmap2 = bitmapDC.SelectObject(pBmpSpan);

		memDC.StretchBlt(rect.left, 0, nWidth, rect.Height()+1, &bitmapDC, 0,0, 1, 24, SRCCOPY);

		bitmapDC.SelectObject(pOldBitmap2);
		*/


		//draw the end piece of the column header
		CBitmap* pOldBitmap3 = bitmapDC.SelectObject(pBmpEnd);
		memDC.BitBlt((rect.right-2), 0, 2, 24, &bitmapDC,0,0,SRCCOPY);
		bitmapDC.SelectObject(pOldBitmap3);

		//For the following items we will just use the
		//right border of the previous items as the left
		//border
		if(hditem1.iOrder==0)
		{
			pOldBitmap = bitmapDC.SelectObject(pBmpStart);
			memDC.BitBlt(rect.left, rect.top, 2, 24, &bitmapDC, 0, 0, SRCCOPY);

			memDC.BitBlt(rect.left, rect.top, m_nCheckBoxHeight, m_nCheckBoxHeight, &bitmapDC, 0, 0, SRCCOPY);

			POINT pt;
			pt.x = 3;
			pt.y = 4;	

			SIZE sz;
			sz.cx = m_nCheckBoxHeight;
			sz.cy = m_nCheckBoxHeight;
			m_cImageList.DrawIndirect(&memDC, m_nChkState, pt, sz, CPoint(0,0));
		}
		else
		{
			memDC.BitBlt(rect.left-1, rect.top, 2, 24, &bitmapDC, 0, 0, SRCCOPY);
			pOldBitmap = bitmapDC.SelectObject(pBmpSpan);
			memDC.BitBlt(rect.left+1, rect.top, 1, 24, &bitmapDC, 0, 0, SRCCOPY);
		}

		bitmapDC.SelectObject(pOldBitmap);

		//Get all the info for the current
		//item so we can draw the text to it
		//in the desired font and style
		DRAWITEMSTRUCT	DrawItemStruct;
		GetItemRect(i, &rectItem);


		DrawItemStruct.CtlType		= 100;
		DrawItemStruct.hDC			= dc.GetSafeHdc();
		DrawItemStruct.itemAction	= ODA_DRAWENTIRE; 
		DrawItemStruct.hwndItem 	= GetSafeHwnd(); 
		DrawItemStruct.rcItem	= rectItem;
		DrawItemStruct.itemID	= i;
		DrawItem(&DrawItemStruct);

		UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_TOP |DT_CENTER | DT_END_ELLIPSIS ;


		CFont font;
		CFont *pFont2 = GetParent()->GetFont();
		CFont *def_font;
		def_font = memDC.SelectObject(pFont2);

		memDC.SetBkMode(TRANSPARENT);
		rectItem.DeflateRect(2,2,2,2);

		TCHAR buf[256];
		HD_ITEM hditem;

		hditem.mask = HDI_TEXT | HDI_FORMAT | HDI_ORDER;
		hditem.pszText = buf;
		hditem.cchTextMax = 255;
		GetItem( DrawItemStruct.itemID, &hditem );

		memDC.DrawText(buf, &rectItem, uFormat);
		memDC.SelectObject(def_font);
	}		
}

BOOL CSkinHeaderCtrl::OnEraseBkgnd(CDC* pDC)
{
	return  FALSE;
}

void CSkinHeaderCtrl::DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
{

}


void CSkinHeaderCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
	RECT rcChk;
	rcChk.left = 6;
	rcChk.top  = 4;
	rcChk.right = 19;
	rcChk.bottom = 17;

	if (PtInRect(&rcChk, point))
	{	
		if (m_nChkState == 1)
		{
			m_nChkState = 2;
		}
		else
		{
			m_nChkState = 1;
		}

		Invalidate(FALSE);

		DWORD ControlID;
		
		if (m_pParentWnd && m_bCheckbox)
		{
			ControlID = MAKELONG(WM_LIST_MSG, m_nCtrlID);
			m_pParentWnd->PostMessage(WM_CTL_MESSAGE, ControlID, m_nChkState);
		}
	}

	CHeaderCtrl::OnLButtonDown(nFlags, point);
}

void CSkinHeaderCtrl::SetCheck(int nCheck)
{
	m_nChkState = nCheck;
	Invalidate(FALSE);
}

